﻿namespace System.ServiceModel.DomainServices.Client
{
    using System;
    using System.Text;

    public abstract class EntityKey
    {
        protected EntityKey()
        {
        }

        public static EntityKey Create(params object[] keyValues)
        {
            object obj2;
            if (keyValues == null)
            {
                throw new ArgumentNullException("keyValues");
            }
            int length = keyValues.Length;
            switch (length)
            {
                case 0:
                    throw new ArgumentException(Resource.EntityKey_EmptyKeyMembers, "keyValues");

                case 1:
                    obj2 = keyValues[0];
                    VerifyKeyValueNotNull(obj2);
                    return (EntityKey) Activator.CreateInstance(typeof(EntityKey<>).MakeGenericType(new Type[] { obj2.GetType() }), new object[] { obj2 });
            }
            object obj3 = keyValues[length - 1];
            VerifyKeyValueNotNull(obj3);
            obj2 = keyValues[length - 2];
            VerifyKeyValueNotNull(obj2);
            EntityKey key = (EntityKey) Activator.CreateInstance(typeof(EntityKey<,>).MakeGenericType(new Type[] { obj2.GetType(), obj3.GetType() }), new object[] { obj2, obj3 });
            for (int i = length - 3; i >= 0; i--)
            {
                obj2 = keyValues[i];
                VerifyKeyValueNotNull(obj2);
                key = (EntityKey) Activator.CreateInstance(typeof(EntityKey<,>).MakeGenericType(new Type[] { obj2.GetType(), key.GetType() }), new object[] { obj2, key });
            }
            return key;
        }

        public static EntityKey Create<T1, T2>(T1 v1, T2 v2)
        {
            return new EntityKey<T1, T2>(v1, v2);
        }

        public static EntityKey Create<T1, T2, T3>(T1 v1, T2 v2, T3 v3)
        {
            return new EntityKey<T1, EntityKey<T2, T3>>(v1, new EntityKey<T2, T3>(v2, v3));
        }

        internal abstract void FormatKey(StringBuilder sb);
        internal static void FormatKeyValue<T>(StringBuilder sb, T value)
        {
            if (sb == null)
            {
                throw new ArgumentNullException("sb");
            }
            if (value == null)
            {
                throw new ArgumentNullException(Resource.EntityKey_CannotBeNull);
            }
            EntityKey key = value as EntityKey;
            if (key != null)
            {
                key.FormatKey(sb);
            }
            else
            {
                if (sb.Length > 0)
                {
                    sb.Append(",");
                }
                sb.Append(value.ToString());
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            this.FormatKey(sb);
            return ("{" + sb.ToString() + "}");
        }

        internal static void VerifyKeyValueNotNull(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", Resource.EntityKey_CannotBeNull);
            }
        }
    }
}

